<html>
<!-- $LastChangedDate: 2009-11-07 22:56:33 -0500 (Sat, 07 Nov 2009) $ -->
<!-- Copyright (C) 2004,2009 Jim Brooks http://www.palomino3d.org -->
<head>
<title>Palomino - Sky Module</title>
<link rel='stylesheet' type='text/css' href='docs.css'>
<link rel='icon' type='image/png' href='images/favicon.png'/>
</head>
<body>

<!-- ----------------------------------------------------------------------- -->
<h1>Palomino - Sky Module</h1>
<p>
&copy;2004,2009&nbsp;&nbsp;Jim E. Brooks
&nbsp;&nbsp;<a href='http://www.palomino3d.org'>http://www.palomino3d.org</a>
</p>
<hr>
<ul>
  <li><a href='index.html'>Index</a></li>
  <li><a href='module_world.html#Latitude and Longitude'>Latitude and Longitude</a></li>
  <li><a href='#Sky'>Sky</a></li>
  <li><a href='#SkyDome'>SkyDome</a></li>
  <li><a href='#SkyDomePainter'>SkyDomePainter</a></li>
  <li><a href='#Clouds'>Clouds</a></li>
  <li><a href='#Sun'>Sun</a></li>
  <li><a href='#Moon'>Moon</a></li>
  <li><a href='#Stars'>Stars</a></li>
</ul>

<!-- ----------------------------------------------------------------------- -->
<hr>
<a name='Sky'></a>
<h2>Sky</h2>
<p><!--date-->[2008/04]</p>
<p>
The Sky object is a Singleton that contains the
sky-related objects such as the
<a href='#SkyDome'>SkyDome</a>, <a href='#Stars'>Stars</a>, clouds, etc.
</p>

<!-- ----------------------------------------------------------------------- -->
<hr>
<a name='SkyDome'></a>
<a name='Sky Dome'></a>
<a name='Skydome'></a>
<h2>Sky Dome</h2>
<p><!--date-->[2008/04]</p>
<p>
The SkyDome class models a 3D sphere that is rendered using smooth shading (vertex color interpolation).
The sky can be painted by specifying a RGBA in terms of a (lat,lon) coordinate.
SkyDome will correlate a (lat,lon) with the nearest vertex and change its color.
</p>
<p>
SkyDome defines a full sphere,
but its drawable geometry can be limited to a northern hemisphere for speed.
This setting is appropriate to whether the
<a href='module_world.html#Planet'>Planet</a> is spherical or flat.
</p>
<p>
In STL terms, SkyDome is a general data container,
and a <a href='#SkyDomePainter'>SkyDomePainter</a> is a specific algorithm.
</p>

<!-- ----------------------------------------------------------------------- -->
<hr>
<a name='SkyDomePainter'></a>
<h2>SkyDomePainter</h2>
<p><!--date-->[2008/04]</p>
<p>
Algorithms to paint the <a href='#SkyDome'>SkyDome</a> are innately specific,
so they are separated as the SkyDomePainter class (functions turned into class methods).
This separation is for factoring, and to allow possibility of painting
a Martian sky with a different implementation of SkyDomePainter.
</p>

<!-- ----------------------------------------------------------------------- -->
<hr>
<a name='Clouds'></a>
<h2>Clouds</h2>
<p><!--date-->[2008/08]</p>
<p>
Implemented using <a href='module_fx.html#ParticleSystem'>ParticleSystem</a>.
Currently, cloud textures are rendered from pre-loaded images (procedural clouds aren't used).
ParticleSystem provides a timer-tick that could animate clouds
(but for speed that capability isn't used).
</p>
<h3>Cloud Sprites and Roll Degree</h3>
<p>
Sprites are view-plane-aligned 3D quads.
When the player rolls the view, the sprites must roll too (Z rotation in eye space).
Every time the view matrix is recomputed, the View class tracks the degree of roll.
This can be done by measuring the angle of the Y axis between
the previous and current view matrixs.
</p>
<pre>
Degree
ComputeMatrixRollDegree( const Matrix&amp; matrix, const Matrix&amp; nextMatrix )
{
    // Invert mapping of current matrix.
    Matrix inverseMatrix = MatrixTranspose( matrix );
    inverseMatrix.SetPosition( Vector3(0,0,0) );

    // Transform the Y axis of the next matrix thru the inverse of the current one.
    const Vector3 nextYAxis = inverseMatrix * Vector3( nextMatrix[Yx],
                                                       nextMatrix[Yy],
                                                       nextMatrix[Yz] );

    // Transformations produce results in absolute space which
    // allows measuring angles in 2D by ignoring a 3rd dimension.
    // Compute 2D angle of current and next Y axis.
    const Vector3 currYAxis( 0.0f, 1.0f, 0.0f );
    const Radian rad = Angle2( Vector2( currYAxis[XX], currYAxis[YY] ),
                               Vector2( nextYAxis[XX], nextYAxis[YY] ) );
    if ( nextYAxis[XX] < 0 )  // for full 360 range
        return Rad2Deg( -rad );
    else
        return Rad2Deg( rad );
}
</pre>

<!-- ----------------------------------------------------------------------- -->
<hr>
<a name='Sun'></a>
<h2>Sun</h2>
<p><!--date-->[2008/04]</p>
<p>
Sun is a stub class.  It just holds the sun's (lat,lon) coordinates.
The sun is actually rendered by <a href='SkyDomePainter'>SkyDomePainter</a>
which paints the sun's aura.
In the future, Sun could be improved by rendering a Sprite image.
</p>

<!-- ----------------------------------------------------------------------- -->
<hr>
<a name='Moon'></a>
<h2>Moon</h2>
<p><!--date-->[2008/04]</p>
<p>
Moon is rendered as a <a href='module_fx.html#Sprite'>Sprite</a>
specified by (lat,lon).
</p>

<!-- ----------------------------------------------------------------------- -->
<hr>
<a name='Stars'></a>
<h2>Stars</h2>
<p><!--date-->[2008/04]</p>
<p>
Stars are simply random white points (no attempt to model real constellations).
The <a href='#SkyDome'>SkyDome</a> can be used to help compute stars,
but the graphical objects for stars would be contained by
the <a href='#Sky'>Sky</a> object.
</p>

<!-- ********************************* END ********************************* -->
<hr>
<p align='center'>
<font size='-2'>
<!-- hhmts start -->
Last modified: Sat Nov  7 14:58:32 CST 2009
<!-- hhmts end -->
</font>
</p>

</body>
</html>
